/*
* st_theme_node_reduce_border_radius:
* @node: a #StThemeNode
+ * @width: The width of the box
+ * @height: The height of the box
* @corners: (array length=4) (out): reduced corners
*
* Implements the corner overlap algorithm mentioned at
*/
static void
st_theme_node_reduce_border_radius (StThemeNode *node,
+ float width,
+ float height,
guint *corners)
{
gfloat scale;
+ node->border_radius[ST_CORNER_TOPRIGHT];
if (sum > 0)
- scale = MIN (node->alloc_width / sum, scale);
+ scale = MIN (width / sum, scale);
/* right */
sum = node->border_radius[ST_CORNER_TOPRIGHT]
+ node->border_radius[ST_CORNER_BOTTOMRIGHT];
if (sum > 0)
- scale = MIN (node->alloc_height / sum, scale);
+ scale = MIN (height / sum, scale);
/* bottom */
sum = node->border_radius[ST_CORNER_BOTTOMLEFT]
+ node->border_radius[ST_CORNER_BOTTOMRIGHT];
if (sum > 0)
- scale = MIN (node->alloc_width / sum, scale);
+ scale = MIN (width / sum, scale);
/* left */
sum = node->border_radius[ST_CORNER_BOTTOMLEFT]
+ node->border_radius[ST_CORNER_TOPLEFT];
if (sum > 0)
- scale = MIN (node->alloc_height / sum, scale);
+ scale = MIN (height / sum, scale);
corners[ST_CORNER_TOPLEFT] = node->border_radius[ST_CORNER_TOPLEFT] * scale;
corners[ST_CORNER_TOPRIGHT] = node->border_radius[ST_CORNER_TOPRIGHT] * scale;
static CoglHandle
st_theme_node_lookup_corner (StThemeNode *node,
+ float width,
+ float height,
StCorner corner_id)
{
CoglHandle texture, material;
cache = st_texture_cache_get_default ();
- st_theme_node_reduce_border_radius (node, radius);
+ st_theme_node_reduce_border_radius (node, width, height, radius);
if (radius[corner_id] == 0)
return COGL_INVALID_HANDLE;
}
static cairo_pattern_t *
-create_cairo_pattern_of_background_gradient (StThemeNode *node)
+create_cairo_pattern_of_background_gradient (StThemeNode *node,
+ float width,
+ float height)
{
cairo_pattern_t *pattern;
NULL);
if (node->background_gradient_type == ST_GRADIENT_VERTICAL)
- pattern = cairo_pattern_create_linear (0, 0, 0, node->alloc_height);
+ pattern = cairo_pattern_create_linear (0, 0, 0, height);
else if (node->background_gradient_type == ST_GRADIENT_HORIZONTAL)
- pattern = cairo_pattern_create_linear (0, 0, node->alloc_width, 0);
+ pattern = cairo_pattern_create_linear (0, 0, width, 0);
else
{
gdouble cx, cy;
- cx = node->alloc_width / 2.;
- cy = node->alloc_height / 2.;
+ cx = width / 2.;
+ cy = height / 2.;
pattern = cairo_pattern_create_radial (cx, cy, 0, cx, cy, MIN (cx, cy));
}
static cairo_pattern_t *
create_cairo_pattern_of_background_image (StThemeNode *node,
+ float width,
+ float height,
gboolean *needs_background_fill)
{
cairo_surface_t *surface;
cairo_matrix_init_identity (&matrix);
get_background_scale (node,
- node->alloc_width, node->alloc_height,
+ width, height,
background_image_width, background_image_height,
&scale_w, &scale_h);
if ((scale_w != 1) || (scale_h != 1))
background_image_height *= scale_h;
get_background_coordinates (node,
- node->alloc_width, node->alloc_height,
+ width, height,
background_image_width, background_image_height,
&x, &y);
cairo_matrix_translate (&matrix, -x, -y);
if (node->background_repeat ||
(x >= 0 &&
y >= 0 &&
- background_image_width - x >= node->alloc_width &&
- background_image_height -y >= node->alloc_height))
+ background_image_width - x >= width &&
+ background_image_height -y >= height))
*needs_background_fill = FALSE;
}
* cases (gradients, background images, etc).
*/
static CoglHandle
-st_theme_node_prerender_background (StThemeNode *node)
+st_theme_node_prerender_background (StThemeNode *node,
+ float actor_width,
+ float actor_height)
{
StBorderImage *border_image;
CoglHandle texture;
ClutterActorBox actor_box;
ClutterActorBox paint_box;
cairo_path_t *interior_path = NULL;
+ float width, height;
border_image = st_theme_node_get_border_image (node);
box_shadow_spec = st_theme_node_get_box_shadow (node);
actor_box.x1 = 0;
- actor_box.x2 = node->alloc_width;
+ actor_box.x2 = actor_width;
actor_box.y1 = 0;
- actor_box.y2 = node->alloc_height;
+ actor_box.y2 = actor_height;
/* If there's a background image shadow, we
* may need to create an image bigger than the nodes
actor_box.y1 += - paint_box.y1;
actor_box.y2 += - paint_box.y1;
- paint_box.x2 += - paint_box.x1;
- paint_box.x1 += - paint_box.x1;
- paint_box.y2 += - paint_box.y1;
- paint_box.y1 += - paint_box.y1;
+ width = paint_box.x2 - paint_box.x1;
+ height = paint_box.y2 - paint_box.y1;
- rowstride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32,
- paint_box.x2 - paint_box.x1);
- data = g_new0 (guchar, (paint_box.y2 - paint_box.y1) * rowstride);
+ rowstride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width);
+ data = g_new0 (guchar, height * rowstride);
/* We zero initialize the destination memory, so it's fully transparent
* by default.
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
- paint_box.x2 - paint_box.x1,
- paint_box.y2 - paint_box.y1,
+ width, height,
rowstride);
cr = cairo_create (surface);
/* TODO - support non-uniform border colors */
get_arbitrary_border_color (node, &border_color);
- st_theme_node_reduce_border_radius (node, radius);
+ st_theme_node_reduce_border_radius (node, width, height, radius);
for (i = 0; i < 4; i++)
border_width[i] = st_theme_node_get_border_width (node, i);
*/
if (node->background_gradient_type != ST_GRADIENT_NONE)
{
- pattern = create_cairo_pattern_of_background_gradient (node);
+ pattern = create_cairo_pattern_of_background_gradient (node, width, height);
draw_solid_background = FALSE;
/* If the gradient has any translucent areas, we need to
if (background_image != NULL)
{
- pattern = create_cairo_pattern_of_background_image (node,
+ pattern = create_cairo_pattern_of_background_image (node, width, height,
&draw_solid_background);
if (shadow_spec && pattern != NULL)
draw_background_image_shadow = TRUE;
has_visible_outline? outline_path : NULL,
actor_box.x1,
actor_box.y1,
- paint_box.x2 - paint_box.x1,
- paint_box.y2 - paint_box.y1);
+ width, height);
cairo_append_path (cr, outline_path);
}
if (interior_path != NULL)
cairo_path_destroy (interior_path);
- texture = cogl_texture_new_from_data (paint_box.x2 - paint_box.x1,
- paint_box.y2 - paint_box.y1,
+ texture = cogl_texture_new_from_data (width, height,
COGL_TEXTURE_NONE,
CLUTTER_CAIRO_FORMAT_ARGB32,
COGL_PIXEL_FORMAT_ANY,
guint border_radius[4];
int corner;
- st_theme_node_reduce_border_radius (node, border_radius);
+ st_theme_node_reduce_border_radius (node, width, height, border_radius);
for (corner = 0; corner < 4; corner ++) {
if (border_radius[corner] * 2 > height ||
node->border_slices_material = COGL_INVALID_HANDLE;
node->corner_material[ST_CORNER_TOPLEFT] =
- st_theme_node_lookup_corner (node, ST_CORNER_TOPLEFT);
+ st_theme_node_lookup_corner (node, width, height, ST_CORNER_TOPLEFT);
node->corner_material[ST_CORNER_TOPRIGHT] =
- st_theme_node_lookup_corner (node, ST_CORNER_TOPRIGHT);
+ st_theme_node_lookup_corner (node, width, height, ST_CORNER_TOPRIGHT);
node->corner_material[ST_CORNER_BOTTOMRIGHT] =
- st_theme_node_lookup_corner (node, ST_CORNER_BOTTOMRIGHT);
+ st_theme_node_lookup_corner (node, width, height, ST_CORNER_BOTTOMRIGHT);
node->corner_material[ST_CORNER_BOTTOMLEFT] =
- st_theme_node_lookup_corner (node, ST_CORNER_BOTTOMLEFT);
+ st_theme_node_lookup_corner (node, width, height, ST_CORNER_BOTTOMLEFT);
/* Use cairo to prerender the node if there is a gradient, or
* background image with borders and/or rounded corners,
|| (has_inset_box_shadow && (has_border || node->background_color.alpha > 0))
|| (background_image && (has_border || has_border_radius))
|| has_large_corners)
- node->prerendered_texture = st_theme_node_prerender_background (node);
+ node->prerendered_texture = st_theme_node_prerender_background (node, width, height);
if (node->prerendered_texture)
node->prerendered_material = _st_create_texture_material (node->prerendered_texture);
for (side_id = 0; side_id < 4; side_id++)
border_width[side_id] = st_theme_node_get_border_width(node, side_id);
- st_theme_node_reduce_border_radius (node, border_radius);
+ st_theme_node_reduce_border_radius (node, width, height, border_radius);
for (corner_id = 0; corner_id < 4; corner_id++)
{
static void
st_theme_node_paint_sliced_border_image (StThemeNode *node,
- const ClutterActorBox *box,
+ float width,
+ float height,
guint8 paint_opacity)
{
gfloat ex, ey;
ty1 = border_top / img_height;
ty2 = (img_height - border_bottom) / img_height;
- ex = node->alloc_width - border_right;
+ ex = width - border_right;
if (ex < 0)
ex = border_right; /* FIXME ? */
- ey = node->alloc_height - border_bottom;
+ ey = height - border_bottom;
if (ey < 0)
ey = border_bottom; /* FIXME ? */
tx2, ty1,
/* top right */
- ex, 0, node->alloc_width, border_top,
+ ex, 0, width, border_top,
tx2, 0.0,
1.0, ty1,
tx2, ty2,
/* mid right */
- ex, border_top, node->alloc_width, ey,
+ ex, border_top, width, ey,
tx2, ty1,
1.0, ty2,
/* bottom left */
- 0, ey, border_left, node->alloc_height,
+ 0, ey, border_left, height,
0.0, ty2,
tx1, 1.0,
/* bottom center */
- border_left, ey, ex, node->alloc_height,
+ border_left, ey, ex, height,
tx1, ty2,
tx2, 1.0,
/* bottom right */
- ex, ey, node->alloc_width, node->alloc_height,
+ ex, ey, width, height,
tx2, ty2,
1.0, 1.0
};
}
if (node->border_slices_material != COGL_INVALID_HANDLE)
- st_theme_node_paint_sliced_border_image (node, &allocation, paint_opacity);
+ st_theme_node_paint_sliced_border_image (node, width, height, paint_opacity);
}
else
{